package com.heima.article.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heima.article.mapper.ApArticleConfigMapper;
import com.heima.article.mapper.ApArticleContentMapper;
import com.heima.article.mapper.ApArticleMapper;
import com.heima.article.mapper.ApCollectionMapper;
import com.heima.article.service.ApArticleService;
import com.heima.article.service.ArticleFreemarkerService;

import com.heima.common.constants.ArticleConstants;
import com.heima.common.redis.CacheService;
import com.heima.model.article.dtos.ArticleDto;
import com.heima.model.article.dtos.ArticleHomeDto;
import com.heima.model.article.dtos.ArticleInfoDto;
import com.heima.model.article.pojos.ApArticle;
import com.heima.model.article.pojos.ApArticleConfig;
import com.heima.model.article.pojos.ApArticleContent;
import com.heima.model.article.pojos.ApCollection;
import com.heima.model.article.vos.HotArticleVo;
import com.heima.model.behavior.pojos.ApLikesBehavior;
import com.heima.model.behavior.pojos.ApReadBehavior;
import com.heima.model.behavior.pojos.ApUnlikesBehavior;
import com.heima.model.common.dtos.PageResponseResult;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.user.pojos.ApUser;
import com.heima.model.user.pojos.ApUserFollow;
import com.heima.model.wemedia.dtos.WmFindNewsCommentsDto;
import com.heima.model.wemedia.dtos.WmNewsPageDto;
import com.heima.model.wemedia.dtos.WmUpdateCommentStatusDto;
import com.heima.model.wemedia.pojos.WmFindNewsComments;
import com.heima.model.wemedia.pojos.WmNewsPage;
import com.heima.model.wemedia.pojos.WmUser;
import com.heima.utils.common.DateUtils;
import com.heima.utils.thread.AppThreadLocalUtil;
import com.heima.utils.thread.WmThreadLocalUtil;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

@Service
@Transactional
public class ApArticleServiceImpl extends ServiceImpl<ApArticleMapper, ApArticle> implements ApArticleService {
    @Autowired
    private ApArticleMapper apArticleMapper;

    private static final Short MAX_PAGE_SIZE = 50;


    /**
     * 加载文章列表
     *
     * @param dto
     * @param type      1 加载更多   2 加载最新
     * @param firstPage true  是首页  flase 非首页
     * @return
     */
    @Override
    public ResponseResult load2(ArticleHomeDto dto, Short type, boolean firstPage) {
        if (firstPage) {
            String jsonString = cacheService.get(ArticleConstants.HOT_ARTICLE_FIRST_PAGE + dto.getTag());
            if (StringUtils.isNotBlank(jsonString)) {
                List<HotArticleVo> hotArticleVoList = JSON.parseArray(jsonString, HotArticleVo.class);
                ResponseResult responseResult = ResponseResult.okResult(hotArticleVoList);
                return responseResult;
            }
        }
        return load(dto, type);
    }


    /**
     * 加载文章列表
     *
     * @param dto
     * @param type 1:加载更多 2:加载最新
     * @return
     */
    @Override
    public ResponseResult load(ArticleHomeDto dto, Short type) {
        //校验参数
        //校验分页条数
        Integer size = dto.getSize();
        if (size == null || size == 0) {
            size = 10;
        }
        size = Math.min(size, MAX_PAGE_SIZE);
        //校验参数type
        if (!type.equals(ArticleConstants.LOADTYPE_LOAD_MORE) || !type.equals(ArticleConstants.LOADTYPE_LOAD_NEW)) {
            type = ArticleConstants.LOADTYPE_LOAD_MORE;
        }
        //频道参数校验
        if (StringUtils.isBlank(dto.getTag())) {
            //频道参数为空
            dto.setTag(ArticleConstants.DEFAULT_TAG);
        }
        //时间校验
        if (dto.getMaxBehotTime() == null) {
            dto.setMaxBehotTime(new Date());
        }
        if (dto.getMinBehotTime() == null) {
            dto.setMinBehotTime(new Date());
        }
        //查询
        List<ApArticle> apArticleList = apArticleMapper.loadArticleList(dto, type);
        return ResponseResult.okResult(apArticleList);
    }

    @Autowired
    private ApArticleConfigMapper apArticleConfigMapper;

    @Autowired
    private ApArticleContentMapper apArticleContentMapper;

    @Autowired
    private ArticleFreemarkerService articleFreemarkerService;

    //保存app端文章
    @Override
    public ResponseResult saveArticle(ArticleDto dto) {
        //1 检查参数
        if (dto == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        ApArticle article = new ApArticle();
        //拷贝属性
        BeanUtils.copyProperties(dto, article);
        //2判断是否存在id
        if (dto.getId() == null) {
            //2.1 id不存在 保存 文章 文章配置 文章内容
            //保存文章
            save(article);

            //保存文章配置
            ApArticleConfig config = new ApArticleConfig(article.getId());
            apArticleConfigMapper.insert(config);

            //保存文章内容
            ApArticleContent content = new ApArticleContent();
            content.setArticleId(article.getId());
            content.setContent(dto.getContent());
            apArticleContentMapper.insert(content);

        } else {
            //2.2 id存在 修改  文章  文章内容
            updateById(article);

            //修改文章内容
            ApArticleContent content = apArticleContentMapper.selectOne(Wrappers.<ApArticleContent>lambdaQuery().eq(ApArticleContent::getArticleId, dto.getId()));
            content.setContent(dto.getContent());
            apArticleContentMapper.updateById(content);
        }

        //异步调用 生成静态文件上传到minio中
        articleFreemarkerService.buildArticleToMinIO(article, dto.getContent());

        //结果返回  article_id 文章的id
        return ResponseResult.okResult(article.getId());
    }

    @Autowired
    private CacheService cacheService;

    /**
     * 加载文章行为-数据回显
     *
     * @param dto
     * @return
     */
    @Override
    public ResponseResult loadArticle(ArticleInfoDto dto) {
        ApUser user = AppThreadLocalUtil.getUser();
        boolean isfollow = false;
        boolean islike = false;
        boolean isunlike = false;
        boolean iscollection = false;
        Map<String, Object> map = new HashMap<>();

        String s = cacheService.lRightPop(dto.getArticleId() + "likes");
        if (s != null) {
            islike = true;
        }
        String s1 = cacheService.lRightPop(user.getId() + "unlikes" + dto.getArticleId());
        if (s1 != null) {
            isunlike = true;
        }

        String s2 = cacheService.lRightPop(user.getId() + "collection");
        if (s2 != null) {
            iscollection = true;
        }

        String s3 = cacheService.lRightPop(dto.getArticleId() + "follow");
        if (s3 != null) {
            isfollow = true;
        }
        map.put("isfollow", isfollow);
        map.put("islike", islike);
        map.put("isunlike", isunlike);
        map.put("iscollection", iscollection);
        return ResponseResult.okResult(map);
    }


    /**
     * 图文数据 分页查询
     *
     * @param dto
     * @return
     */
    @Override
    public PageResponseResult newPage(WmNewsPageDto dto) {
        dto.checkParam();
        //类型转换
        Date beginDate = DateUtils.stringToDate(dto.getBeginDate());
        Date endDate = DateUtils.stringToDate(dto.getEndDate());
        //分页查询
        IPage pageInfo = new Page(dto.getPage(), dto.getSize());
        LambdaQueryWrapper<ApArticle> lqw = Wrappers.<ApArticle>lambdaQuery()
                .between(ApArticle::getPublishTime, beginDate, endDate)
                .select(ApArticle::getId, ApArticle::getTitle, ApArticle::getLikes, ApArticle::getCollection, ApArticle::getComment, ApArticle::getViews);
        lqw.orderByDesc(ApArticle::getPublishTime);

        pageInfo = page(pageInfo, lqw);

        PageResponseResult responseResult = new PageResponseResult(dto.getPage(), dto.getSize(), (int) pageInfo.getTotal());
        responseResult.setData(pageInfo.getRecords());
        return responseResult;
    }

    /**
     * 图文数据统计
     *
     * @param beginDate
     * @param endDate
     * @return
     */
    @Override
    public ResponseResult newsDimension(Date beginDate, Date endDate) {
        Map map = apArticleMapper.findNewsDimension(beginDate, endDate);
        return ResponseResult.okResult(map);
    }

    /**
     * 查看评论列表
     *
     * @param dto
     * @return
     */
    @Override
    public PageResponseResult findNewsComments(WmFindNewsCommentsDto dto) {
        Integer page = dto.getPage();

        dto.setPage((dto.getPage() - 1) * dto.getSize());

        List<WmFindNewsComments> newsComments = apArticleMapper.findNewsComments(dto);
        int commentsCount = apArticleMapper.findNewsCommentsCount(dto);

        PageResponseResult responseResult = new PageResponseResult(page, dto.getSize(), commentsCount);
        responseResult.setData(newsComments);
        return responseResult;
    }


}
